package com.whsxt.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.whsxt.dao.ProdEsDao;
import com.whsxt.es.ProdEs;
import com.whsxt.service.SearchService;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.index.query.AbstractQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author: caoqingwen
 * @CreateTime: 2021-03-19 15:33
 * @Description:
 */
@Service
@Slf4j
public class SearchServiceImpl implements SearchService {


    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    @Autowired
    private ProdEsDao prodEsDao;


    /**
     * 根据标签id查询商品
     *
     * @param tagId
     * @param current
     * @param size
     * @return
     */
    @Override
    public Page<ProdEs> findProdByTagId(Long tagId, Integer current, Integer size) {
        TermQueryBuilder termQuery = QueryBuilders.termQuery("tagList", tagId);
        Page<ProdEs> page = new Page<>(current, size);
        return query(termQuery, page, null, null);





        /*//构建查询条件
        TermQueryBuilder termQuery = QueryBuilders.termQuery("tagList", tagId);
        //组装查询
        NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(termQuery)
                .withPageable(PageRequest.of(current, size))
                .build();
        //开始查询
        SearchHits<ProdEs> searchHits = elasticsearchRestTemplate.search(query, ProdEs.class);
        //组装对象
        Page<ProdEs> page = new Page<>(current, size);

        List<ProdEs> prodEs = new ArrayList<>();
        searchHits.forEach(searchHit -> {
            ProdEs prod = searchHit.getContent();
            prodEs.add(prod);
        });

        page.setTotal(searchHits.getTotalHits());
        page.setRecords(prodEs);
        return page;*/
    }


    /**
     * 根据关键字查询商品
     *
     * @param prodName
     * @param current
     * @param size
     * @param sort
     * @return
     */
    @Override
    public Page<ProdEs> findProdByKeyWord(String prodName, Integer current, Integer size, Integer sort) {

        MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("prodName", prodName);
        Page<ProdEs> page = new Page<>(current, size);
        return query(matchQuery, page, prodName, sort);


       /* //构建查询条件
        MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("prodName", prodName);
        //组装条件
        //排序
        SortBuilder sortBuilder = doSort(sort);

        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder().withQuery(matchQuery)
                .withPageable(PageRequest.of(current, size))
                .withSort(sortBuilder);
        //高亮
        if (!"*".equals(prodName)) {
            HighlightBuilder.Field field = new HighlightBuilder.Field("prodName");
            field.preTags("<span style='color:red'>");
            field.postTags("</span>");
            queryBuilder.withHighlightFields(field);
        }

        //查询
        SearchHits<ProdEs> searchHits = elasticsearchRestTemplate.search(queryBuilder.build(), ProdEs.class);

        //组装对象
        Page<ProdEs> page = new Page<>(current, size);
        ArrayList<ProdEs> prodEs = new ArrayList<>();
        searchHits.forEach(searchHit -> {
            ProdEs prod = searchHit.getContent();
            //处理高亮
            if (!"*".equals(prodName)) {
                List<String> prodNameList = searchHit.getHighlightField("prodName");
                if (!CollectionUtils.isEmpty(prodNameList)) {
                    String newName = prodNameList.get(0);
                    prod.setProdName(newName);
                }
            }
            prodEs.add(prod);
        });

        page.setTotal(searchHits.getTotalHits());
        page.setRecords(prodEs);
        return page;*/
    }


    public Page<ProdEs> query(AbstractQueryBuilder abstractQueryBuilder, Page<ProdEs> page, String keyWord, Integer sort) {

        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder().withQuery(abstractQueryBuilder)
                .withPageable(PageRequest.of((int) page.getCurrent() - 1, (int) page.getSize()));

        //排序
        if (null != sort) {
            SortBuilder sortBuilder = doSort(sort);
            queryBuilder.withSort(sortBuilder);
        }

        //高亮
        if (!StringUtils.isEmpty(keyWord)) {
            HighlightBuilder.Field field = new HighlightBuilder.Field("prodName");
            field.preTags("<span style='color:red'>");
            field.postTags("</span>");
            queryBuilder.withHighlightFields(field);
        }

        //查询
        SearchHits<ProdEs> searchHits = elasticsearchRestTemplate.search(queryBuilder.build(), ProdEs.class);

        //组装对象
        ArrayList<ProdEs> prodEs = new ArrayList<>();
        searchHits.forEach(searchHit -> {
            ProdEs prod = searchHit.getContent();
            //处理高亮
            if (!StringUtils.isEmpty(keyWord)) {
                List<String> prodNameList = searchHit.getHighlightField("prodName");
                if (!CollectionUtils.isEmpty(prodNameList)) {
                    String newName = prodNameList.get(0);
                    prod.setProdName(newName);
                }
            }
            prodEs.add(prod);
        });

        page.setTotal(searchHits.getTotalHits());
        page.setRecords(prodEs);
        return page;
    }


    /**
     * 排序
     *
     * @param sort
     * @return
     */
    private SortBuilder doSort(Integer sort) {
        switch (sort) {
            case 0:
                //好评
                return SortBuilders.fieldSort("positiveRating").order(SortOrder.DESC);
            case 1:
                //销量
                return SortBuilders.fieldSort("soldNum").order(SortOrder.DESC);
            case 2:
                //价格
                return SortBuilders.fieldSort("price").order(SortOrder.ASC);
            default:
                throw new RuntimeException();
        }
    }


    /**
     * 根据ids查询商品信息===提供远程调用
     *
     * @param prodIds
     * @return
     */
    @Override
    public List<ProdEs> findProdEsByIds(List<Long> prodIds) {
        List<ProdEs> allById = (List<ProdEs>) prodEsDao.findAllById(prodIds);
        return allById;
    }


    /**
     * 根据分类id查询商品信息
     *
     * @param cateGoryId
     * @return
     */
    @Override
    public Page<ProdEs> searchProdByKCateGoryId(Long cateGoryId) {
        TermQueryBuilder termQuery = QueryBuilders.termQuery("cateGoryId", cateGoryId);
        Page<ProdEs> page = new Page<>(1, 10);
        return query(termQuery, page, null, null);
    }
}
